步骤 4:添加生成器表达式

生成器表达式 在构建系统生成期间进行评估,以生成特定于每个构建配置的信息。

生成器表达式 可以在许多目标属性的上下文中使用,例如 LINK_LIBRARIESINCLUDE_DIRECTORIESCOMPILE_DEFINITIONS 等。它们还可以在使用命令填充这些属性时使用,例如 target_link_libraries()target_include_directories()target_compile_definitions() 等。

生成器表达式 可用于启用条件链接、编译时使用的条件定义、条件包含目录等等。条件可以基于构建配置、目标属性、平台信息或任何其他可查询信息。

有不同类型的 生成器表达式,包括逻辑表达式、信息表达式和输出表达式。

逻辑表达式用于创建条件输出。基本表达式是 01 表达式。 $<0:...> 的结果为空字符串,而 $<1:...> 的结果是 ... 的内容。它们还可以嵌套。

练习 1 - 使用生成器表达式添加编译器警告标志

生成器表达式 的一个常见用法是根据条件添加编译器标志,例如用于语言级别或警告的标志。一个不错的模式是将此信息与 INTERFACE 目标关联,允许此信息传播。

目标

在构建时添加编译器警告标志,但在安装版本中不添加。

有用资源

要编辑的文件

  • CMakeLists.txt

入门

打开文件 Step4/CMakeLists.txt 并完成 TODO 1TODO 4

首先,在顶级 CMakeLists.txt 文件中,我们需要将 cmake_minimum_required() 设置为 3.15。在本练习中,我们将使用 CMake 3.15 中引入的生成器表达式。

接下来,我们添加项目所需的编译器警告标志。由于警告标志因编译器而异,因此我们使用 COMPILE_LANG_AND_ID 生成器表达式来控制在给定语言和一组编译器 ID 的情况下应用哪些标志。

构建和运行

创建一个名为 Step4_build 的新目录,运行 cmake 可执行文件或 cmake-gui 来配置项目,然后使用您选择的构建工具或使用 cmake --build . 从构建目录进行构建。

mkdir Step4_build
cd Step4_build
cmake ../Step4
cmake --build .

解决方案

更新 cmake_minimum_required() 以要求至少 CMake 版本 3.15

TODO 1:点击显示/隐藏答案
TODO 1:CMakeLists.txt
cmake_minimum_required(VERSION 3.15)

接下来,我们确定系统当前使用哪个编译器进行构建,因为警告标志因我们使用的编译器而异。这是通过 COMPILE_LANG_AND_ID 生成器表达式完成的。我们将结果设置在变量 gcc_like_cxxmsvc_cxx 中,如下所示

TODO 2:点击显示/隐藏答案
TODO 2:CMakeLists.txt
set(gcc_like_cxx "$<COMPILE_LANG_AND_ID:CXX,ARMClang,AppleClang,Clang,GNU,LCC>")
set(msvc_cxx "$<COMPILE_LANG_AND_ID:CXX,MSVC>")

接下来,我们添加项目所需的编译器警告标志。使用我们的变量 gcc_like_cxxmsvc_cxx,我们可以使用另一个生成器表达式仅在变量为真时应用相应的标志。我们使用 target_compile_options() 将这些标志应用于我们的接口库。

TODO 3:点击显示/隐藏答案
TODO 3:CMakeLists.txt
target_compile_options(tutorial_compiler_flags INTERFACE
  "$<${gcc_like_cxx}:-Wall;-Wextra;-Wshadow;-Wformat=2;-Wunused>"
  "$<${msvc_cxx}:-W3>"
)

最后,我们只希望在构建期间使用这些警告标志。我们的已安装项目的使用者不应该继承我们的警告标志。为了指定这一点,我们将 TODO 3 中的标志包装在一个使用 BUILD_INTERFACE 条件的生成器表达式中。生成的完整代码如下所示

TODO 4:点击显示/隐藏答案
TODO 4:CMakeLists.txt
target_compile_options(tutorial_compiler_flags INTERFACE
  "$<${gcc_like_cxx}:$<BUILD_INTERFACE:-Wall;-Wextra;-Wshadow;-Wformat=2;-Wunused>>"
  "$<${msvc_cxx}:$<BUILD_INTERFACE:-W3>>"
)